package com.xiaodu.jpa.repository;

import com.xiaodu.jpa.entity.ProductEntity;
import org.springframework.data.annotation.QueryAnnotation;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.*;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author: dutianjie
 * @date: 2021/4/20
 * @version: v1.0.0
 * @description: 描述
 **/
@Repository
public interface ProductRepository extends
        /*CrudRepository*/
        /*PagingAndSortingRepository*/
        JpaRepository<ProductEntity, String>,
        JpaSpecificationExecutor<ProductEntity> {


// 批量查询，p_name like {#pName} and price >= #{price}
    List<ProductEntity> findAllByPNameLikeAndPriceGreaterThanEqual(String pName, Long price);

    // hql 语句  表名即实体名若用了@Entity 指定则是@Entity指定的名称
    @Query("select p from product p")
    List<ProductEntity> selectAll();

    // hql  带参数； 使用? 加index 进行占位符
    @Query("select p from product p where p.price = ?1")
    List<ProductEntity> selectByPrice(Long price);
    // hql 使用 :field 参数占位符
    @Query("select p from product p where p.price = :price")
    List<ProductEntity> selectByPrice2(@Param("price") Long price);


    // 分页查询, 需要传递 pageable
    @Query("select p from product p where p.price = :price")
    Page<ProductEntity> pageByPrice(@Param("price") Long price, Pageable pageable);


    // 使用原生sqlsql
    @Query(value = "select * from t_product", nativeQuery = true)
    List<ProductEntity> selectAlls();
    // 使用 ？index 接收参数
    @Query(value = "select * from t_product where p_name = ?1", nativeQuery = true)
    List<ProductEntity> selectByName(String pName);

    // 使用 :field 接收
    @Query(value = "select * from t_product where p_name = :pName", nativeQuery = true)
    List<ProductEntity> selectByName2(@Param("pName") String pName);

    // 接收对象  使用 :#{#field} 接收
    @Query(value = "select * from t_product where p_name = :#{#product.pName}", nativeQuery = true)
    List<ProductEntity> selectByName3(@Param("product") ProductEntity productEntity);

    // 执行update insert delete  语句，需要加上@Modifying  和 @Transactional 语句
    @Transactional(timeout = 10)
    @Query("update product set pName = :#{#productEntity.pName} where pId = :#{#productEntity.pId}")
    @Modifying
    int updateProductNameById(@Param("productEntity") ProductEntity productEntity);

}
